package common

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"os/exec"
	"time"
)

// CmdWithTimeout 执行命令并设置超时时间
// common.CmdWithTimeout(10*time.Second, "sh", "-c", cmd)
func CmdWithTimeout(timeout time.Duration, shell string, args ...string) (stdout, stderr string, exitCode int, err error) {
	// 设置超时时间为5秒
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	// 创建命令
	cmd := exec.CommandContext(ctx, shell, args...)

	// 分别捕获标准输出和错误输出
	var stdoutBuf, stderrBuf bytes.Buffer
	cmd.Stdout = &stdoutBuf
	cmd.Stderr = &stderrBuf

	// 执行命令
	err = cmd.Run()
	stdout = stdoutBuf.String()
	stderr = stderrBuf.String()

	if err != nil {
		var exitErr *exec.ExitError
		if errors.As(err, &exitErr) {
			exitCode = exitErr.ExitCode()
		} else if ctx.Err() == context.DeadlineExceeded {
			fmt.Println("命令执行超时")
			return stdout, stderr, 133, ctx.Err()
		} else {
			fmt.Printf("命令执行失败: %v\n", err)
			return stdout, stderr, exitCode, err
		}
	}

	return stdout, stderr, exitCode, nil
}
